import {
  checkBillInCompany, checkBillNeedUpdate, checkCompanyCategoryNameExist,
  checkCompanyExist,
  checkCompanyNameExist,
  checkUserCompanyCreator,
  checkUserInCompany, checkUserInCompanyRole,
  queryCheckId,
  updateUserCompanyRole
} from "./utils.js";
import sequelize from "../models/init.js";
import companyDao from "../Dao/company.js";
import companyUserDao from "../Dao/company_user.js";
import {CompanyRole} from "../roleTypes/CompanyRole.js";
import {getNow, httpResult} from "../utils/utils.js";
import billDao from "../Dao/bill.js";
import categoryDao from "../Dao/category.js";
import userDao from "../Dao/user.js";

// 创建公司
export const createCompany = async (req, res) => {
  const {id, name} = req.body;
  await queryCheckId(id);
  // 检查公司名称是否已存在
  await checkCompanyNameExist(name);
  const newCompany = {
    "role": 1,
    "company_id": -1,
    "companyName": name
  };
  const t = await sequelize.transaction();
  try {
    // 创建新公司
    const company = await companyDao.createCompany(name, id, t);
    newCompany.company_id = company.id;
    // 添加公司用户 创建者
    await companyUserDao.createCompanyUser(company.id, CompanyRole.CREATOR, id, t);
    await t.commit();
  } catch (e) {
    await t.rollback();
    console.log(e, 'createCompany Error');
    throw new Error('创建公司失败');
  }
  res.json(httpResult.success({result: true, company: newCompany}));
};

// 获取公司管理员
export const getCompanyAdmin = async (req, res) => {
  const {id, companyId} = req.body;
  await queryCheckId(id);
  const company = await companyDao.getCompany(companyId);
  if (!company) {
    throw new Error('公司不存在');
  }
  // 检查用户是否在该公司
  await checkUserInCompany(companyId, id);
  const companyAdminList = await companyUserDao.getCompanyRoleUserList(companyId, CompanyRole.ADMIN);
  res.json(httpResult.success({result: true, companyAdminList}));
};

// 任命公司管理员
export const addCompanyAdmin = async (req, res) => {
  const {id, companyId, userId} = req.body;
  if(Number(id) === Number(userId)) {
    throw new Error('不能任命自己为管理员');
  }
  await queryCheckId(id);
  await queryCheckId(userId);
  await checkCompanyExist(companyId);
  // 判断发起请求的用户是否是公司创建者
  await checkUserCompanyCreator(companyId, id);
  // 任命管理员
  await updateUserCompanyRole(companyId, userId, CompanyRole.ADMIN);
  res.json(httpResult.success({result: true}));
};

// 移除公司管理员
export const removeCompanyAdmin = async (req, res) => {
  const {id, companyId, userId} = req.body;
  if(Number(id) === Number(userId)) {
    throw new Error('任命自己为员工');
  }
  await queryCheckId(id);
  await queryCheckId(userId);
  await checkCompanyExist(companyId);
  // 判断发起请求的用户是否是公司创建者
  await checkUserCompanyCreator(companyId, id);
  // 移除管理员
  await updateUserCompanyRole(companyId, userId, CompanyRole.MEMBER);
  res.json(httpResult.success({result: true}));
};

// 获取公司员工列表
export const getCompanyUserList = async (req, res) => {
  const {id, companyId} = req.body;
  await queryCheckId(id);
  await checkCompanyExist(companyId);
  // 判断发起请求的用户是否是公司员工
  await checkUserInCompany(companyId, id);
  // 获取公司员工列表
  const companyUserList = await companyUserDao.getCompanyUserList(companyId);
  // 获取员工的名称
  let ids = [];
  for (let i = 0; i < companyUserList.length; i++){
    ids.push(companyUserList[i].user_id);
  }
  // 根据ids 查询名称
  const userList = await userDao.findUsers(ids);
  // 根据id将员工的名称和手机号和邮箱赋值给公司员工列表
  for (let i = 0; i < companyUserList.length; i++){
    companyUserList[i].user_name = userList[i].user_name;
    companyUserList[i].mobile = userList[i].mobile;
    companyUserList[i].email = userList[i].email;
  }
  res.json(httpResult.success({result: true, companyUserList}));
};

// 添加公司员工
export const addCompanyUser = async (req, res) => {
  const {id, companyId, userId} = req.body;
  await queryCheckId(id);
  await queryCheckId(userId);
  await checkCompanyExist(companyId);
  // 判断发起请求的用户是否是公司创建者或者管理员
  await checkUserInCompanyRole(companyId, id, [CompanyRole.ADMIN, CompanyRole.CREATOR]);
  // 添加公司员工
  await updateUserCompanyRole(companyId, userId, CompanyRole.MEMBER);
  const userCompanyNew = await companyUserDao.getRoleByUserId(company_id, userId);
  const user = await userDao.findUserLock(userId);
  res.json(httpResult.success({result: true, user: {
    ...userCompanyNew,
      user_name: user.user_name,
      mobile: user.mobile,
      email: user.email,
    }}));
};

// 添加公司员工 根据名称或者邮箱或者手机号
export const addCompanyUserByNameOrEmailOrMobile = async (req, res) => {
  const {id, companyId, username, email, mobile} = req.body;
  if(!username && !email && !mobile) {
    throw new Error('请输入用户名或邮箱');
  }
  await queryCheckId(id);
  await checkCompanyExist(companyId);
  // 判断发起请求的用户是否是公司创建者或者管理员
  await checkUserInCompanyRole(companyId, id, [CompanyRole.ADMIN, CompanyRole.CREATOR]);
  // 获取用户的id
  const user = await userDao.findUserByNameOrEmailOrMobile(username, email, mobile);
  const userCompany = await companyUserDao.getRoleByUserId(companyId, user.id);
  if(userCompany) {
    throw new Error('该用户已经是公司员工');
  }
  // 添加公司员工
  await updateUserCompanyRole(companyId, user.id, CompanyRole.MEMBER);
  const userCompanyNew = await companyUserDao.getRoleByUserId(companyId, user.id);
  res.json(httpResult.success({result: true, user: {
    ...userCompanyNew,
      user_name: user.user_name,
      email: user.email,
      mobile: user.mobile
    }}));
};

// 删除公司员工
export const deleteCompanyUser = async (req, res) => {
  const {id, companyId, userId} = req.body;
  // console.log(id, companyId, userId, '删除公司员工');
  await queryCheckId(id);
  await queryCheckId(userId);
  await checkCompanyExist(companyId);
  // 判断被删除人员不是创建者 ---- 成员和管理员可以删除
  await checkUserInCompanyRole(companyId, userId, [CompanyRole.ADMIN, CompanyRole.MEMBER]);
  // 判断发起请求的用户是否是公司创建者或者管理员
  await checkUserInCompanyRole(companyId, id, [CompanyRole.ADMIN, CompanyRole.CREATOR]);
  // 删除公司员工
  await companyUserDao.deleteCompanyUser(companyId, userId);
  res.json(httpResult.success({result: true}));
};

// 获取公司某一账单历史记录
export const getCompanyBillHistory = async (req, res) => {
  const {id, companyId, billId} = req.body;
  await queryCheckId(id);
  await checkCompanyExist(companyId);
  // 判断发起请求的用户是否是公司员工
  await checkUserInCompany(companyId, id);
  // 获取公司某一账单历史记录
  let billHistory = await billDao.getBillHisById(billId);
  res.json(httpResult.success({result: true, billHistory}));
};


// 添加公司账单
export const addCompanyBill = async (req, res) => {
  const {id, companyId, category, remark, amount, isComplete, billTime} = req.body;
  // await queryCheckId(id);
  await checkCompanyExist(companyId);
  // 判断发起请求的用户是否是公司员工
  await checkUserInCompany(companyId, id);
  // 添加公司账单
  let addRes = await billDao.createCompanyBill(category, remark, amount, id, companyId, isComplete, billTime, null);
  res.json(httpResult.success({result: true, bill: addRes}));
};

// 查询公司的账单
export const getCompanyBills = async (req, res) => {
  const {id, companyId} = req.body;
  await queryCheckId(id);
  await checkCompanyExist(companyId);
  // 判断发起请求的用户是否是公司员工
  await checkUserInCompany(companyId, id);
  // 查询公司的账单
  const bills = await billDao.getCompanyBills(companyId);
  res.json(httpResult.success({result: true, bills}));
};

// 修改公司账单
export const updateCompanyBill = async (req, res) => {
  const {id, companyId, category, remark, amount, isComplete, billId, billTime} = req.body;
  await queryCheckId(id);
  await checkCompanyExist(companyId);
  // 判断发起请求的用户是否是公司员工
  await checkUserInCompany(companyId, id);
  // 获取原来的账单数据
  const oldBill = await billDao.getBillById(billId);
  checkBillNeedUpdate({category, remark, amount, isComplete}, {
    category: oldBill.category,
    remark: oldBill.remark,
    amount: oldBill.amount,
    isComplete: oldBill.is_complete
  });
  // 存储新帐单结果
  let bill = null;
  // 修改公司账单
  const t = await sequelize.transaction();
  try {
    // 修改账单记录
    await billDao.updateCompanyBill(billId, category, remark, amount, isComplete, getNow(), id, billTime, t);
    // 添加一个旧的账单记录
    await billDao.createCompanyUpdateBill(oldBill.category, oldBill.remark, oldBill.amount, oldBill.creator_id, oldBill.company_id, oldBill.is_complete, oldBill.id, oldBill.create_time, oldBill.bill_time, t);
    // 获取新的结果
    bill = await billDao.getBillById(billId, t);
    await t.commit();
  } catch (e) {
    console.log(e.message, '修改公司账单失败');
    await t.rollback();
    throw new Error('修改公司账单失败');
  }
  res.json(httpResult.success({result:true, bill}));
};

// 删除公司账单
export const deleteCompanyBill = async (req, res) => {
  const {id, companyId, billId} = req.body;
  await queryCheckId(id);
  await checkCompanyExist(companyId);
  // 判断发起请求的用户是否是公司员工
  await checkUserInCompanyRole(companyId, id, [CompanyRole.ADMIN, CompanyRole.CREATOR]);
  // 检查账单是否是该公司的
  let bill = await checkBillInCompany(companyId, billId);
  if(bill.from_id !== null) {
    throw new Error('账单记录不能删除');
  }
  // 删除公司账单
  await billDao.deleteBill(billId);
  res.json(httpResult.success({result:true}));
};

// 获取公司账单类型
export const getCompanyBillCategory = async (req, res) => {
  const {id, companyId} = req.body;
  await queryCheckId(id);
  await checkCompanyExist(companyId);
  // 判断发起请求的用户是否是公司员工
  await checkUserInCompany(companyId, id);
  let categories = await categoryDao.getCompanyCategory(companyId);
  res.json(httpResult.success({result:true, categories}));
};

// 添加公司账单类型
export const addCompanyBillCategory = async (req, res) => {
  const {id, companyId, name, is_out} = req.body;
  await queryCheckId(id);
  await checkCompanyExist(companyId);
  // 判断发起请求的用户是否是公司员工
  await checkUserInCompanyRole(companyId, id, [CompanyRole.ADMIN, CompanyRole.CREATOR]);
  // 检查账单类型是否已存在
  await checkCompanyCategoryNameExist(name, companyId);
  // 添加公司账单类型
  let category = await categoryDao.addCompanyCategory(name, companyId, is_out);
  res.json(httpResult.success({result:true, category}));
};

// 删除公司账单类型
export const deleteCompanyBillCategory = async (req, res) => {
  const {id, companyId, categoryId} = req.body;
  await queryCheckId(id);
  await checkCompanyExist(companyId);
  // 判断发起请求的用户是否是公司员工
  await checkUserInCompanyRole(companyId, id, [CompanyRole.ADMIN, CompanyRole.CREATOR]);
  // 删除公司账单类型
  await categoryDao.deleteCategory(categoryId);
  res.json(httpResult.success({result: true}));
};
